home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16_Src.lha / Python16_Source / Modules / readline.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-04  |  9.8 KB  |  436 lines

  1. /* This module makes GNU readline available to Python.  It has ideas
  2.  * contributed by Lee Busby, LLNL, and William Magro, Cornell Theory
  3.  * Center.  The completer interface was inspired by Lele Gaifax.
  4.  *
  5.  * More recently, it was largely rewritten by Guido van Rossum who is
  6.  * now maintaining it.
  7.  */
  8.  
  9. /* Standard definitions */
  10. #include "Python.h"
  11. #include <setjmp.h>
  12. #include <signal.h>
  13. #include <errno.h>
  14.  
  15. #ifdef HAVE_UNISTD_H
  16. #include <unistd.h> /* For isatty() */
  17. #endif
  18.  
  19. /* GNU readline definitions */
  20. /* If you have string.h, you might need to add yourself to this #if... [cjh] */
  21. #if defined(__BEOS__)
  22. #undef HAVE_CONFIG_H
  23. /* At max warnings, we need protos for everything. [cjh] */
  24. #include <readline/readline.h>
  25. #include <readline/history.h>
  26. #include <unistd.h>
  27. #else
  28. #include <readline/readline.h> /* You may need to add an -I option to Setup */
  29.  
  30. extern int rl_parse_and_bind();
  31. extern int rl_read_init_file();
  32. extern int rl_insert_text();
  33. extern int rl_bind_key();
  34. extern int rl_bind_key_in_map();
  35. extern int rl_initialize();
  36. extern int add_history();
  37. extern Function *rl_event_hook;
  38. #endif
  39.  
  40. /* Pointers needed from outside (but not declared in a header file). */
  41. extern int (*PyOS_InputHook)();
  42. extern char *(*PyOS_ReadlineFunctionPointer) Py_PROTO((char *));
  43.  
  44.  
  45. /* Exported function to send one line to readline's init file parser */
  46.  
  47. static PyObject *
  48. parse_and_bind(self, args)
  49.     PyObject *self;
  50.     PyObject *args;
  51. {
  52.     char *s, *copy;
  53.     if (!PyArg_ParseTuple(args, "s:parse_and_bind", &s))
  54.         return NULL;
  55.     /* Make a copy -- rl_parse_and_bind() modifies its argument */
  56.     /* Bernard Herzog */
  57.     copy = malloc(1 + strlen(s));
  58.     if (copy == NULL)
  59.         return PyErr_NoMemory();
  60.     strcpy(copy, s);
  61.     rl_parse_and_bind(copy);
  62.     free(copy); /* Free the copy */
  63.     Py_INCREF(Py_None);
  64.     return Py_None;
  65. }
  66.  
  67. static char doc_parse_and_bind[] = "\
  68. parse_and_bind(string) -> None\n\
  69. Parse and execute single line of a readline init file.\
  70. ";
  71.  
  72.  
  73. /* Exported function to parse a readline init file */
  74.  
  75. static PyObject *
  76. read_init_file(self, args)
  77.     PyObject *self;
  78.     PyObject *args;
  79. {
  80.     char *s = NULL;
  81.     if (!PyArg_ParseTuple(args, "|z:read_init_file", &s))
  82.         return NULL;
  83.     errno = rl_read_init_file(s);
  84.     if (errno)
  85.         return PyErr_SetFromErrno(PyExc_IOError);
  86.     Py_INCREF(Py_None);
  87.     return Py_None;
  88. }
  89.  
  90. static char doc_read_init_file[] = "\
  91. read_init_file([filename]) -> None\n\
  92. Parse a readline initialization file.\n\
  93. The default filename is the last filename used.\
  94. ";
  95.  
  96.  
  97. /* Exported function to specify a word completer in Python */
  98.  
  99. static PyObject *completer = NULL;
  100. static PyThreadState *tstate = NULL;
  101.  
  102. static PyObject *begidx = NULL;
  103. static PyObject *endidx = NULL;
  104.  
  105. /* get the beginning index for the scope of the tab-completion */
  106. static PyObject *
  107. get_begidx(self, args)
  108.     PyObject *self;
  109.     PyObject *args;
  110. {
  111.     if(!PyArg_NoArgs(args)) {
  112.         return NULL;
  113.     } 
  114.     Py_INCREF(begidx);
  115.     return begidx;
  116. }
  117.  
  118. static char doc_get_begidx[] = "\
  119. get_begidx() -> int\n\
  120. get the beginning index of the readline tab-completion scope";
  121.  
  122. /* get the ending index for the scope of the tab-completion */
  123. static PyObject *
  124. get_endidx(self, args)
  125.     PyObject *self;
  126.     PyObject *args;
  127. {
  128.      if(!PyArg_NoArgs(args)) {
  129.         return NULL;
  130.     } 
  131.     Py_INCREF(endidx);
  132.     return endidx;
  133. }
  134.  
  135. static char doc_get_endidx[] = "\
  136. get_endidx() -> int\n\
  137. get the ending index of the readline tab-completion scope";
  138.  
  139.  
  140. /* set the tab-completion word-delimiters that readline uses */
  141.  
  142. static PyObject *
  143. set_completer_delims(self, args)
  144.     PyObject *self;
  145.     PyObject *args;
  146. {
  147.     char *break_chars;
  148.  
  149.     if(!PyArg_ParseTuple(args, "s:set_completer_delims", &break_chars)) {
  150.         return NULL;
  151.     }
  152.     free(rl_completer_word_break_characters);
  153.     rl_completer_word_break_characters = strdup(break_chars);
  154.     Py_INCREF(Py_None);
  155.     return Py_None;
  156. }
  157.  
  158. static char doc_set_completer_delims[] = "\
  159. set_completer_delims(string) -> None\n\
  160. set the readline word delimiters for tab-completion";
  161.  
  162.  
  163. /* get the tab-completion word-delimiters that readline uses */
  164.  
  165. static PyObject *
  166. get_completer_delims(self, args)
  167.     PyObject *self;
  168.     PyObject *args;
  169. {
  170.     if(!PyArg_NoArgs(args)) {
  171.         return NULL;
  172.     }
  173.     return PyString_FromString(rl_completer_word_break_characters);
  174. }
  175.     
  176. static char doc_get_completer_delims[] = "\
  177. get_completer_delims() -> string\n\
  178. get the readline word delimiters for tab-completion";
  179.  
  180. static PyObject *
  181. set_completer(self, args)
  182.     PyObject *self;
  183.     PyObject *args;
  184. {
  185.     PyObject *function = Py_None;
  186.     if (!PyArg_ParseTuple(args, "|O:set_completer", &function))
  187.         return NULL;
  188.     if (function == Py_None) {
  189.         Py_XDECREF(completer);
  190.         completer = NULL;
  191.         tstate = NULL;
  192.     }
  193.     else if (PyCallable_Check(function)) {
  194.         PyObject *tmp = completer;
  195.         Py_INCREF(function);
  196.         completer = function;
  197.         Py_XDECREF(tmp);
  198.         tstate = PyThreadState_Get();
  199.     }
  200.     else {
  201.         PyErr_SetString(PyExc_TypeError,
  202.                 "set_completer(func): argument not callable");
  203.         return NULL;
  204.     }
  205.     Py_INCREF(Py_None);
  206.     return Py_None;
  207. }
  208.  
  209. static char doc_set_completer[] = "\
  210. set_completer([function]) -> None\n\
  211. Set or remove the completer function.\n\
  212. The function is called as function(text, state),\n\
  213. for i in [0, 1, 2, ...] until it returns a non-string.\n\
  214. It should return the next possible completion starting with 'text'.\
  215. ";
  216.  
  217. /* Exported function to read the current line buffer */
  218.  
  219. static PyObject *
  220. get_line_buffer(self, args)
  221.     PyObject *self;
  222.         PyObject *args;
  223. {
  224.     if (!PyArg_NoArgs(args))
  225.         return NULL;
  226.     return PyString_FromString(rl_line_buffer);
  227. }
  228.  
  229. static char doc_get_line_buffer[] = "\
  230. get_line_buffer() -> string\n\
  231. return the current contents of the line buffer.\
  232. ";
  233.  
  234. /* Exported function to insert text into the line buffer */
  235.  
  236. static PyObject *
  237. insert_text(self, args)
  238.     PyObject *self;
  239.     PyObject *args;
  240. {
  241.     char *s;
  242.     if (!PyArg_ParseTuple(args, "s:insert_text", &s))
  243.         return NULL;
  244.     rl_insert_text(s);
  245.     Py_INCREF(Py_None);
  246.     return Py_None;
  247. }
  248.  
  249.  
  250. static char doc_insert_text[] = "\
  251. insert_text(string) -> None\n\
  252. Insert text into the command line.\
  253. ";
  254.  
  255.  
  256. /* Table of functions exported by the module */
  257.  
  258. static struct PyMethodDef readline_methods[] =
  259. {
  260.     {"parse_and_bind", parse_and_bind, 1, doc_parse_and_bind},
  261.     {"get_line_buffer", get_line_buffer, 0, doc_get_line_buffer},
  262.     {"insert_text", insert_text, 1, doc_insert_text},
  263.     {"read_init_file", read_init_file, 1, doc_read_init_file},
  264.     {"set_completer", set_completer, 1, doc_set_completer},
  265.     {"get_begidx", get_begidx, 0, doc_get_begidx},
  266.     {"get_endidx", get_endidx, 0, doc_get_endidx},
  267.  
  268.     {"set_completer_delims", set_completer_delims, METH_VARARGS,
  269.         doc_set_completer_delims},
  270.     {"get_completer_delims", get_completer_delims, 0,
  271.         doc_get_completer_delims},
  272.     {0, 0}
  273. };
  274.  
  275. /* C function to call the Python completer. */
  276.  
  277. static char *
  278. on_completion(text, state)
  279.     char *text;
  280.     int state;
  281. {
  282.     char *result = NULL;
  283.     if (completer != NULL) {
  284.         PyObject *r;
  285.         PyThreadState *save_tstate;
  286.         /* Note that readline is called with the interpreter
  287.            lock released! */
  288.         save_tstate = PyThreadState_Swap(NULL);
  289.         PyEval_RestoreThread(tstate);
  290.         r = PyObject_CallFunction(completer, "si", text, state);
  291.         if (r == NULL)
  292.             goto error;
  293.         if (r == Py_None) {
  294.             result = NULL;
  295.         }
  296.         else {
  297.             char *s = PyString_AsString(r);
  298.             if (s == NULL)
  299.                 goto error;
  300.             result = strdup(s);
  301.         }
  302.         Py_DECREF(r);
  303.         goto done;
  304.       error:
  305.         PyErr_Clear();
  306.         Py_XDECREF(r);
  307.       done:
  308.         PyEval_SaveThread();
  309.         PyThreadState_Swap(save_tstate);
  310.     }
  311.     return result;
  312. }
  313.  
  314.  
  315. /* a more flexible constructor that saves the "begidx" and "endidx"
  316.  * before calling the normal completer */
  317.  
  318. char **
  319. flex_complete(text, start, end)
  320.     char *text;
  321.     int start;
  322.     int end;
  323. {
  324.     Py_XDECREF(begidx);
  325.     Py_XDECREF(endidx);
  326.     begidx = PyInt_FromLong((long) start);
  327.     endidx = PyInt_FromLong((long) end);
  328.     return completion_matches(text, *on_completion);
  329. }
  330.  
  331. /* Helper to initialize GNU readline properly. */
  332.  
  333. static void
  334. setup_readline()
  335. {
  336.     rl_readline_name = "python";
  337.     /* Force rebind of TAB to insert-tab */
  338.     rl_bind_key('\t', rl_insert);
  339.     /* Bind both ESC-TAB and ESC-ESC to the completion function */
  340.     rl_bind_key_in_map ('\t', rl_complete, emacs_meta_keymap);
  341.     rl_bind_key_in_map ('\033', rl_complete, emacs_meta_keymap);
  342.     /* Set our completion function */
  343.     rl_attempted_completion_function = (CPPFunction *)flex_complete;
  344.     /* Set Python word break characters */
  345.     rl_completer_word_break_characters =
  346.         strdup(" \t\n`~!@#$%^&*()-=+[{]}\\|;:'\",<>/?");
  347.         /* All nonalphanums except '.' */
  348.  
  349.     begidx = PyInt_FromLong(0L);
  350.     endidx = PyInt_FromLong(0L);
  351.     /* Initialize (allows .inputrc to override)
  352.      *
  353.      * XXX: A bug in the readline-2.2 library causes a memory leak
  354.      * inside this function.  Nothing we can do about it.
  355.      */
  356.     rl_initialize();
  357. }
  358.  
  359.  
  360. /* Interrupt handler */
  361.  
  362. static jmp_buf jbuf;
  363.  
  364. /* ARGSUSED */
  365. static RETSIGTYPE
  366. onintr(sig)
  367.     int sig;
  368. {
  369.     longjmp(jbuf, 1);
  370. }
  371.  
  372.  
  373. /* Wrapper around GNU readline that handles signals differently. */
  374.  
  375. static char *
  376. call_readline(prompt)
  377.     char *prompt;
  378. {
  379.     int n;
  380.     char *p, *q;
  381.     RETSIGTYPE (*old_inthandler)();
  382.     old_inthandler = signal(SIGINT, onintr);
  383.     if (setjmp(jbuf)) {
  384. #ifdef HAVE_SIGRELSE
  385.         /* This seems necessary on SunOS 4.1 (Rasmus Hahn) */
  386.         sigrelse(SIGINT);
  387. #endif
  388.         signal(SIGINT, old_inthandler);
  389.         return NULL;
  390.     }
  391.     rl_event_hook = PyOS_InputHook;
  392.     p = readline(prompt);
  393.     signal(SIGINT, old_inthandler);
  394.  
  395.     /* We must return a buffer allocated with PyMem_Malloc. */
  396.     if (p == NULL) {
  397.         p = PyMem_Malloc(1);
  398.         if (p != NULL)
  399.             *p = '\0';
  400.         return p;
  401.     }
  402.     n = strlen(p);
  403.     if (n > 0)
  404.         add_history(p);
  405.     /* Copy the malloc'ed buffer into a PyMem_Malloc'ed one and
  406.        release the original. */
  407.     q = p;
  408.     p = PyMem_Malloc(n+2);
  409.     if (p != NULL) {
  410.         strncpy(p, q, n);
  411.         p[n] = '\n';
  412.         p[n+1] = '\0';
  413.     }
  414.     free(q);
  415.     return p;
  416. }
  417.  
  418.  
  419. /* Initialize the module */
  420.  
  421. static char doc_module[] =
  422. "Importing this module enables command line editing using GNU readline.";
  423.  
  424. DL_EXPORT(void)
  425. initreadline()
  426. {
  427.     PyObject *m;
  428.  
  429.     m = Py_InitModule4("readline", readline_methods, doc_module,
  430.                (PyObject *)NULL, PYTHON_API_VERSION);
  431.     if (isatty(fileno(stdin))) {
  432.         PyOS_ReadlineFunctionPointer = call_readline;
  433.         setup_readline();
  434.     }
  435. }
  436.